home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-02
/
tpfast40.zip
/
TPFSTR.ASM
< prev
next >
Wrap
Assembly Source File
|
1991-11-14
|
52KB
|
938 lines
; _______________________________________________________________
; | |
; | CopyRight (c) 1989,1990 Steven Lutrov |
; |_______________________________________________________________|____
; | | |
; | program title : faststr.asm | | ___
; | author : Steven Lutrov | | |
; | revision : 4.00 | | |
; | date : 1991-11-01 | | |
; | language : turbo assembler | | |
; | | | |
; | description : assembly functions for string manipulation. | | |
; | : tested on turbo pascal 5.0 & 5.5 | | |
; | | | |
; |_______________________________________________________________| | |
; | | |
; |________________________________________________________________| |
; | |
; |_________________________________________________________________|
;
code segment word public
assume cs:code,ds:data
public changechar,compare,stringend,deletechar,deleteleft,deleteright
public leftend,lowercase,overwrite,padcentre,padends,padleft,padright
public replace,rightend,seekstring,stringof,uppercase,wordcount
;-------------------------------------------------------------------------------
;procedure changechar(var strx: stype; search,replace :char);
;-------------------------------------------------------------------------------
;
data segment
extrn TPFError :byte
data ends
;
;
changechar proc far
push bp ;save bp
mov bp,sp ;set up stack frame
mov TPFError,0 ;assume char found
les di,dword ptr[bp+10] ;es:di pts to strx
sub dx,dx ;flags that a char found
mov al,[bp+6] ;get replacement char
mov ah,[bp+8] ;search character
sub cx,cx ;clear cx
mov cl,es:[di] ;get string length
jcxz changechar3 ;quit if null string
changechar1: inc di ;forward string ptr
cmp es:[di],ah ;search char?
jne changechar2 ;jump ahead if not
mov es:[di],al ;else change char
inc dx ;flag that a char found
changechar2: loop changechar1 ;go do next char
or dx,dx ;test if char found
jnz changechar4 ;jump ahead if so
changechar3: inc TPFError ;else 1 = char not found
changechar4: pop bp ;restore bp and quit
ret 8
changechar endp
;-------------------------------------------------------------------------------
;function compare(strg1,strg2: stype): boolean;
;-------------------------------------------------------------------------------
;
compare proc far
mov bx,sp ;bx pts to stack
push ds ;save turbo's ds
les di,ss:dword ptr[bx+8] ;es:di pts to strg1
lds si,ss:dword ptr[bx+4] ;ds:si pts to strg2
sub cx,cx ;clear cx
mov cl,[si] ;get strg2 length
cmp cl,es:[di] ;equal to strg1 length?
jne compare6 ;quit if not
jcxz compare5 ;quit if both null
compare1: inc di ;forward strg1 ptr
inc si ;forward strg2 ptr
mov al,[si] ;get strg2 char
cmp al,es:[di] ;compare to strg1 char
je compare4 ;loop if equal
cmp al,122 ;above lower case vals?
ja compare6 ;quit if so
cmp al,97 ;lower case char?
jnae compare2 ;jump ahead if not
sub al,32 ;make lower case
jmp short compare3 ;go test it
compare2: cmp al,90 ;above upper case vals?
ja compare6 ;quit if so
cmp al,65 ;upper case char?
jnae compare6 ;quit if not
add al,32 ;make lower case
compare3: cmp al,es:[di] ;compare to strg1 char
jne compare6 ;quit if not equal
compare4: loop compare1 ;go do next char
compare5: mov al,1 ;return true
jmp short compare7 ;jump ahead
compare6: mov al,0 ;return false
compare7: pop ds ;restore ds and quit
ret 8
compare endp
;-------------------------------------------------------------------------------
;function stringend(strx: stype; numberchars :integer): stype;
;-------------------------------------------------------------------------------
;
data segment
extrn TPFError :byte
data ends
;
;
stringend proc far
push bp ;save bp
mov bp,sp ;set up stack frame
push ds ;save ds
les di,dword ptr[bp+12] ;es:di pts to return strx
lds si,dword ptr[bp+8] ;ds:si pts to source strx
sub cx,cx ;clear cx
mov es:[di],cl ;return null string if error
mov cl,[bp+6] ;get numberchars (255 max)
sub bx,bx ;clear bx
mov bl,[si] ;strx length in bx
mov dl,1 ;1 = null string
or bl,bl ;test for null string
jz stringend3 ;quit routine if null
dec dl ;0 = no error
cmp cx,bx ;numberchars < length?
jbe stringend1 ;jump ahead if so
mov cx,bx ;else return whole string
mov dl,2 ;2 = numberchars greater than length
stringend1: mov es:[di],cl ;return strx descriptor
sub bx,cx ;length minus numberchars
inc di ;forward return strx ptr to first char
inc si ;save for source strx
add si,bx ;add starting offset to source
stringend2: cld ;direction forward
rep movsb ;move the portion of the string
stringend3: pop ds ;restore ds
mov TPFError,dl ;set TPFError
pop bp ;restore bp and quit
ret 6
stringend endp
;-------------------------------------------------------------------------------
;procedure deletechar(var strx: stype; ch :char);
;-------------------------------------------------------------------------------
;
data segment
extrn TPFError :byte
data ends
;
;
;
deletechar proc far
cld ;set direction flag
mov TPFError,1 ;1 = char not found
push bp ;save bp
push ds ;save ds
mov bp,sp ;set up stack frame
les di,dword ptr [bp+10] ;get string address
mov al,[bp+8] ;get char to delete
sub bp,bp ;use bp as TPFError flag
push es ;push es...
pop ds ;...then copy into ds
mov bx,di ;bx will pt to descriptor
sub cx,cx ;clear cx
mov cl,es:[di] ;get string length
jcxz deletechar3 ;quit if null string
inc di ;pt di to start of string
mov si,di ;copy into si
cld ;direction forward in movsb
deletechar1: cmp [si],al ;check for the character
je deletechar2 ;jump if char found
movsb ;move the char
loop deletechar1 ;go check next char
jmp short deletechar3 ;finished
deletechar2: inc si ;forward source ptr
dec byte ptr[bx] ;decrease string descriptor
inc bp ;flag that char found
loop deletechar1 ;go check next char
deletechar3: pop ds ;restore ds
or bp,bp ;test bp for zero
jz deletechar4 ;jump if no match found
dec TPFError ;else TPFError = 0
deletechar4: pop bp ;restore bp and quit
ret 6
deletechar endp
;-------------------------------------------------------------------------------
;procedure deleteleft(var strx: stype; border :char);
;-------------------------------------------------------------------------------
;
data segment
extrn TPFError :byte
data ends
;
;
deleteleft proc far
mov TPFError,0 ;assume no error
push ds ;ds is changed
push bp ;save bp
mov bp,sp ;set up stack frame
les di,dword ptr [bp+10] ;es:di pts to string
lds si,dword ptr [bp+10] ;so does ds:si
mov si,di ;keep si at descriptor
mov al,[bp+8] ;get the border character
pop bp ;restore bp
sub cx,cx ;clear cx
mov cl,es:[di] ;string length in cx
jcxz deleteleft1 ;quit if null
mov bx,cx ;copy of string length in bx
inc di ;pt to first byte of string
cld ;direction forward
repne scasb ;look for the border character
jnz deleteleft1 ;quit if can't find char
mov dx,di ;copy of di to dx
dec dx ;point to char before
sub dx,si ;number characters to delete
dec dx ;don't delete border char
mov cx,bx ;old string length
sub cx,dx ;new string length
mov [si],cl ;set new string length
inc si ;point si to start of string
xchg di,si ;reverse pointers for movsb
dec si ;don't remove border char
rep movsb ;move the characters
pop ds ;restore ds
ret 6 ;quit
deleteleft1: pop ds ;---error case:
inc TPFError ;1 = null string or char not found
ret 6 ;quit
deleteleft endp
;-------------------------------------------------------------------------------
;procedure deleteright(var strx: stype; border :char);
;-------------------------------------------------------------------------------
;
data segment
extrn TPFError :byte
data ends
;
;
deleteright proc far
push bp ;save bp
mov bp,sp ;set up stack frame
les di,dword ptr [bp+8] ;load string address
mov si,di ;keep si at descriptor
mov al,[bp+6] ;get the border character
sub cx,cx ;clear cx
mov TPFError,1 ;1 = null string
mov cl,es:[di] ;string length in cx
jcxz deleteright3 ;quit if null
add di,cx ;point di to end of string
deleteright1: cmp [di],al ;test for the border char
je deleteright2 ;if found, jump ahead
dec di ;else, point to next char
loop deleteright1 ;go test next char
jmp short deleteright3 ;char not found
deleteright2: mov es:[si],cl ;set new string length
dec TPFError ;no error
deleteright3: pop bp ;restore bp and quit
ret 6
deleteright endp
;-------------------------------------------------------------------------------
;function leftend(var strx: stype; border :char): stype;
;-------------------------------------------------------------------------------
;
data segment
extrn TPFError :byte
data ends
;
;
leftend proc far
mov dl,1 ;1 = border char not found
push bp ;save bp
mov bp,sp ;set up stack frame
push ds ;save ds
les di,dword ptr[bp+8] ;es:di pts to strx
sub cx,cx ;clear cx
mov cl,es:[di] ;string length to cx
jcxz leftend2 ;quit if zero
inc di ;pt to 1st byte of strx
mov bx,di ;copy start position
cld ;direction forward
mov al,[bp+6] ;border character
repne scasb ;search for the character
jnz leftend1 ;not found, skip ptr dec
dec di ;pull back ptr
dec dl ;TPFError = 0, no error
leftend1: sub di,bx ;distance to char
mov cx,di ;use as counter
mov ax,es ;transfer es...
mov ds,ax ;to ds
mov si,bx ;now ds:si pts to start of strx
leftend2: les di,dword ptr[bp+12] ;now es:di pts to return string
mov es:[di],cl ;set return descriptor
jcxz leftend3 ;jump ahead if null strx
inc di ;forward ptr
rep movsb ;move the string
leftend3: pop ds ;restore ds
mov TPFError,dl ;set TPFError
pop bp ;restore bp and quit
ret 6
leftend endp
;-------------------------------------------------------------------------------
;procedure lowercase(var strx: stype);
;-------------------------------------------------------------------------------
;
lowercase proc far
mov bx,sp ;bx points to stack
les di,ss:dword ptr[bx+4] ;es:di pts to string
sub cx,cx ;clear cx
mov cl,es:[di] ;get string length
jcxz lowercase3 ;quit if null
lowercase1: inc di ;pt to next char of strx
cmp es :byte ptr [di],'Z' ;test high char
ja lowercase2 ;skip ahead if above
cmp es :byte ptr [di],'A' ;test low char
jb lowercase2 ;skip ahead if below
add es :byte ptr [di],32 ;change the char
lowercase2: loop lowercase1 ;go test next character
lowercase3: ret 4
lowercase endp
;-------------------------------------------------------------------------------
;procedure overwrite(var strx: stype; substrg: stype; position :integer);
;-------------------------------------------------------------------------------
;
data segment
extrn TPFError :byte
data ends
;
;
overwrite proc far
mov TPFError,0 ;assume no error
push bp ;save bp
mov bp,sp ;set up stack frame
push ds ;ds is changed
les di,dword ptr [bp+12] ;es:di pts to strx
mov bx,di ;bx points to strx
sub cx,cx ;clear cx
mov cl,[bp+6] ;position in cx
jcxz overwrite2 ;quit if zero
cmp cl,es:[di] ;is position within strx?
ja overwrite2 ;quit if not
mov dx,cx ;keep for error check
add di,cx ;add to string ptr
lds si,dword ptr [bp+8] ;ds:si pts to substring
mov cl,[si] ;get the string descriptor
jcxz overwrite2 ;quit if null
add dx,cx ;dx = substr endchar + 1
sub dl,es:[bx] ;subtract string length
cmp dl,1 ;will substring fit?
jg overwrite3 ;if not, quit routine
overwrite1: inc si ;pt to next substrg char
mov dl,[si] ;get the char
mov es:[di],dl ;insert into the string
inc di ;pt to next char of strx
loop overwrite1 ;go do next character
pop ds ;restore ds
jmp short overwrite5 ;terminate without error
overwrite2: mov al,1 ;1 = position not in string
jmp short overwrite4 ;jump ahead
overwrite3: mov al,2 ;2 = substring won't fit
overwrite4: pop ds ;restore ds
mov TPFError,al ;set TPFError
overwrite5: pop bp ;restore bp and quit
ret 10
overwrite endp
;-------------------------------------------------------------------------------
;procedure padcentre(var strx: stype; ch :char; position,length :integer);
;-------------------------------------------------------------------------------
;
data segment
extrn TPFError :byte
data ends
;
;
padcentre proc far
push bp ;save bp
mov bp,sp ;set up stack frame
mov TPFError,1 ;1 = error
les di,dword ptr[bp+12] ;es:di pts to strx
mov si,di ;copy in si
sub dx,dx ;clear dx
mov dl,[bp+6] ;new strx length in dx (255 max)
or dx,dx ;test for zero length
jz padcentre6 ;quit if zero
mov bx,dx ;copy of length in bx
sub cx,cx ;clear cx
mov cl,es:[di] ;get current strx length
cmp cx,dx ;compare to new length
jae padcentre6 ;quit if longer
mov es:[di],dl ;set new strx length
sub dx,cx ;dx = number pad chars
sub ax,ax ;clear ax
mov al,[bp+8] ;get position
or ax,ax ;test for 0
jnz padcentre1 ;jump if not 0
inc ax ;else make 1
padcentre1: cmp ax,cx ;past end of string?
jna padcentre2 ;jump ahead if not
add di,cx ;offset to end of strx
jmp short padcentre4 ;go write pad chars
padcentre2: add si,bx ;add to target
add di,bx ;add to source
sub di,dx ;source minus number pad chars
sub cx,ax ;subtract from strx len
inc cx ;ax pts from 0, adjust
padcentre3: mov al,es:[di] ;get a char
mov es:[si],al ;shift it upwards
dec di ;pull back source ptr
dec si ;target ptr too
loop padcentre3 ;do next char
padcentre4: mov cx,dx ;number pad characters
mov al,[bp+10] ;get pad character
padcentre5: inc di ;forward ptr
mov es:[di],al ;write pad character
loop padcentre5 ;go do the next
dec TPFError ;0 = no error
padcentre6: pop bp ;restore bp and quit
ret 10
padcentre endp
;-------------------------------------------------------------------------------
;procedure padends(var strx: stype; ch :char; length :integer);
;-------------------------------------------------------------------------------
;
data segment
extrn TPFError :byte
data ends
;
;
padends proc far
push bp ;save bp
mov bp,sp ;set up stack frame
mov TPFError,1 ;1 = error
les di,dword ptr[bp+10] ;es:di pts to strx
mov si,di ;copy in si
sub dx,dx ;clear dx
mov dl,[bp+6] ;new strx length in dx
or dx,dx ;test for zero length
jz padends7 ;quit if zero
sub cx,cx ;clear cx
mov cl,es:[di] ;get strx length
cmp cx,dx ;is strx gt new length
jae padends7 ;quit if true
mov es:[di],dl ;set new strx length
push di ;copy of start of string
sub dx,cx ;dx = number pad chars
mov bx,dx ;copy to bx
shr bx,1 ;chars div 2
sub dx,bx ;dx is same or 1 larger
add di,cx ;pt to end of strx
add si,dx ;offset for upward shift
add si,cx ;plus string length
or cx,cx ;test for null string
jnz padends1 ;jump ahead if not null
sub bx,bx ;
mov bl,[bp+6] ;otherwise set at right padding
jmp short padends3 ;jump to rightside padding
padends1: push si ;save end position
padends2: mov al,es:[di] ;get a char
mov es:[si],al ;shift it
dec di ;dec source ptr
dec si ;dec target ptr
loop padends2 ;go do next
pop si ;restore end position
padends3: mov al,[bp+8] ;get the pad char
mov cx,bx ;number to pad on right
jcxz padends5 ;jump ahead if zero
padends4: inc si ;forward ptr
mov es:[si],al ;write pad char on right
loop padends4 ;go do next
padends5: pop di ;di pts to bottom of strx
mov cx,dx ;number pad chars on left
or cx,cx ;test for zero
jz padends7 ;quit if zero
padends6: inc di ;forward ptr
mov es:[di],al ;write pad char on left
loop padends6 ;go do next
dec TPFError ;0 = no error
padends7: pop bp ;restore bp and quit
ret 8
padends endp
;-------------------------------------------------------------------------------
;procedure padleft(var strx: stype; ch :char; length :integer);
;-------------------------------------------------------------------------------
;
data segment
extrn TPFError :byte
data ends
;
;
padleft proc far
push bp ;save bp
mov bp,sp ;set up stack frame
mov TPFError,1 ;1 = error
push ds ;save ds
les di,dword ptr[bp+10] ;get string address
push es ;push es...
pop ds ;...then load into ds
sub cx,cx ;clear cx
mov cl,es:[di] ;string length in cl
mov bx,[bp+6] ;new string length in bl
dec bx ;dec bx for test
cmp bx,254 ;in range?
ja padleft2 ;quit if not
inc bx ;readjust
cmp cl,bl ;compare the two lengths
jae padleft2 ;quit if old len >= new
mov es:[di],bl ;set new string length
mov si,di ;pt si to descriptor
add si,cx ;now pt si to string end
add di,bx ;pt di to new string end
sub bx,cx ;number of spaces to pad
std ;set direction flag
rep movsb ;move old string right
mov cx,bx ;spaces to pad in cx
mov al,[bp+8] ;get pad character
padleft1: mov [di],al ;insert pad char
dec di ;move to next position
loop padleft1 ;go do next char
pop ds ;restore ds
dec TPFError ;0 = no error
jmp short padleft3 ;jump ahead and quit
padleft2: pop ds ;exit with error
padleft3: pop bp ;restore bp and quit
ret 8
padleft endp
;-------------------------------------------------------------------------------
;procedure padright(var strx: stype; ch :char; length :integer);
;-------------------------------------------------------------------------------
;
data segment
extrn TPFError :byte
data ends
;
;
padright proc far
push bp ;save bp
mov bp,sp ;set up stack frame
mov TPFError,1 ;1 = error
les di,dword ptr[bp+10] ;get string address
sub cx,cx ;clear cx
mov cl,es:[di] ;string length in cl
mov bx,[bp+6] ;new string length
dec bx ;dec bx for test
cmp bx,254 ;in range?
ja padright2 ;quit if not
inc bx ;readjust
cmp cl,bl ;compare the two lengths
jae padright2 ;quit if old len>=new len
mov es:[di],bl ;set new string length
add di,cx ;point di to end of strx
sub bx,cx ;sub old len from new len
mov cx,bx ;use as counter
mov al,[bp+8] ;get pad character
padright1: inc di ;increment pointer
mov es:[di],al ;insert a pad char
loop padright1 ;go do next char
dec TPFError ;0 = no error
padright2: pop bp ;restore bp and quit
ret 8
padright endp
;-------------------------------------------------------------------------------
;procedure replace(var strx: stype; substrg: stype; position,chars :integer);
;-------------------------------------------------------------------------------
;
data segment
extrn TPFError :byte
data ends
;
;
replace proc far
push bp ;save bp
mov bp,sp ;set up stack frame
push ds ;save ds too
mov TPFError,1 ;1 = error has occured
les di,dword ptr[bp+14] ;es:di pts to strx
sub cx,cx ;clear cx
mov byte ptr[bp+7],cl ;use byte as if word
mov cl,es:[di] ;get strx length
or cx,cx ;test for null string
jnz replace2 ;jump ahead if not
replace1: jmp replace9 ;else quit routine
replace2: sub bx,bx ;clear bx
mov bl,[bp+8] ;position to bx
or bx,bx ;position 0?
jz replace1 ;quit if zero
cmp bx,cx ;within strx?
jnbe replace1 ;quit if not
lds si,dword ptr[bp+10] ;ds:si pts to substrg
sub dx,dx ;clear dx
mov dl,[si] ;substring length
or dx,dx ;test for null
jz replace1 ;quit if null
mov ax,cx ;strx length
sub ax,bx ;minus position
inc ax ;number deletable chars
cmp ax,[bp+6] ;cmp to num chars to del
jb replace9 ;quit if not enough chars
mov ax,[bp+6] ;chars to delete
cmp ax,dx ;num chars del/replace
ja replace3 ;must shift chars down
jb replace5 ;must shift chars up
add di,bx ;no shift, di to overlay
jmp short replace7 ;no write substring
replace3: sub ax,dx ;strx shortened this much
sub cx,ax ;new string length
mov es:[di],cl ;set descriptor
add di,bx ;pt to substrg position
mov si,di ;copy to si
add si,dx ;pt to end of substrg + 1
sub cx,bx ;chars following substrg
inc cx ;adjust
mov bx,si ;end of substring pos
add bx,ax ;forward to shift point
replace4: mov al,es:[bx] ;get a char
mov es:[si],al ;move it downward
inc si ;inc target ptr
inc bx ;inc source ptr
loop replace4 ;loop till finished
jmp short replace7 ;go write substring
replace5: neg ax ;dx minus ax in ax
add ax,dx ;ax = increased strx len
add cx,ax ;new length
mov es:[di],cl ;set descriptor
mov si,di ;si pts to start of strx
add di,bx ;point di to substrg pos
add si,cx ;si pts to end of strx
mov bx,si ;copy to bx
sub bx,ax ;move to shift point
sub cx,[bp+8] ;length minus position
dec cx ;adjust
jcxz replace7 ;boundary case
replace6: mov al,es:[bx] ;get a character
mov es:[si],al ;move it upwards
dec si ;dec target ptr
dec bx ;get source ptr
loop replace6 ;loop till finished
replace7: lds si,dword ptr[bp+10] ;point ds:si back to substrg
inc si ;forward si to first char
replace8: mov cl,[si] ;get char from substring
mov es:[di],cl ;move to strx
inc si ;forward source ptr
inc di ;forward target ptr
dec dx ;dec substring ctr
jnz replace8 ;loop till finished
pop ds ;restore ds
dec TPFError ;0 = no error
jmp short replace10 ;jump ahead
replace9: pop ds ;terminate with error
replace10: pop bp ;restore bp and quit
ret 12
replace endp
;-------------------------------------------------------------------------------
;function rightend(var strx: stype; border :char): stype;
;-------------------------------------------------------------------------------
;
data segment
extrn TPFError :byte
data ends
;
;
rightend proc far
push bp ;save bp
mov bp,sp ;set up stack frame
push ds ;save ds
mov dl,1 ;1 = border char not found
les di,dword ptr[bp+8] ;es:di pts to strx
sub cx,cx ;clear cx
mov cl,es:[di] ;string length to cx
jcxz rightend2 ;quit if zero
add di,cx ;pt to last byte of strx
mov si,di ;copy start position
std ;direction flag backward
mov al,[bp+6] ;border character
repne scasb ;search for the character
jnz rightend1 ;skip inc if not found
inc di ;discard border char
dec dl ;TPFError = 0, no error
rightend1: inc di ;step pointer back
sub si,di ;figure number characters
inc si ;adjust
mov cx,si ;use as counter
mov ax,es ;transfer es...
mov ds,ax ;to ds
mov si,di ;ds:si pts to strx
rightend2: les di,dword ptr[bp+12] ;now es:di pts to return string
mov es:[di],cl ;set return descriptor
jcxz rightend3 ;jump ahead if null strx
inc di ;forward ptr
cld ;direction flag forward
rep movsb ;move the string
rightend3: pop ds ;restore ds
mov TPFError,dl ;set TPFError
pop bp ;restore bp and quit
ret 6
rightend endp
;-------------------------------------------------------------------------------
;function seekstring(strx,substrg: stype; startpt :integer) :integer;
;-------------------------------------------------------------------------------
;
data segment
extrn TPFError :byte
data ends
;
;
seekstring proc far
push bp ;save bp
mov bp,sp ;set up stack frame
push ds ;save turbo's ds
lds si,dword ptr[bp+12] ;ds:si pts to strx
les di,dword ptr[bp+8] ;ds:di pts to substrg
sub cx,cx ;clear cx
mov cl,[bp+6] ;get startpt
mov bp,1 ;1 = startpt out of range
jcxz seekstring11 ;quit if zero
mov dl,es:[di] ;substr length in dl
inc di ;di pts 1st chr of substr
inc bp ;2 = substrg is null
or dl,dl ;substr length non-zero?
jnz seekstring21 ;continue if so
seekstring11: jmp seekstring1 ;error: quit routine
seekstring21: mov dh,[si] ;strx length in dh
dec bp ;1 = strx is null
or dh,dh ;test for null
jz seekstring11 ;quit if null
mov bl,cl ;startpt
add bl,dl ;substrg length
dec bl ;adjust
cmp bl,dh ;compare to strx length
ja seekstring11 ;quit if out of range
mov bp,0 ;0 = no error
mov bl,cl ;startpt to pos counter
dec bl ;adjust
sub dh,cl ;sub from search len
inc dh ;adjust
add si,cx ;begin search at startpt
seekstring31: mov al,es:[di] ;get char from of substr
mov ah,al ;copy in ah
cmp al,97 ;low end of lower case
jb seekstring41 ;jump if below
cmp al,122 ;upper end of lower case
ja seekstring51 ;neither upper nor lower
sub ah,32 ;make ah upper case
jmp short seekstring51 ;go test both
seekstring41: cmp al,65 ;low end of upper case
jb seekstring51 ;neither upper nor lower
cmp al,90 ;high end of upper case
ja seekstring51 ;neither upper nor lower
add ah,32 ;make ah lower case
seekstring51: inc bl ;inc strx pos counter
or dh,dh ;counter = zero?
jz seekstring111 ;quit if so
dec dh ;dec length counter
mov bh,[si] ;get char from strx
cmp bh,al ;test for match
je seekstring61 ;jump if found
cmp bh,ah ;2nd test for match
je seekstring61 ;jump if found
inc si ;forward strx ptr
jmp short seekstring51 ;go check next char
seekstring61: cmp dl,1 ;single char substring?
je seekstring1 ;if so, not a match
sub cx,cx ;clear cx
mov cl,dl ;cx = substr length
dec cl ;1st char already matched
push si ;save strx position
push di ;save substr position
seekstring71: inc si ;pt to nxt char of strx
inc di ;pt to nxt char of substr
mov al,es:[di] ;get char from of substr
mov ah,al ;copy in ah
cmp al,97 ;low end of lower case
jb seekstring81 ;jump if below
cmp al,122 ;upper end of lower case
ja seekstring91 ;neither upper nor lower
sub ah,32 ;make ah upper case
jmp short seekstring91 ;go test both
seekstring81: cmp al,65 ;low end of upper case
jb seekstring91 ;neither upper nor lower
cmp al,90 ;high end of upper case
ja seekstring91 ;neither upper nor lower
add ah,32 ;make ah lower case
seekstring91: mov bh,[si] ;get char from strx
cmp bh,al ;test for match
je seekstring101 ;jump if found
cmp bh,ah ;2nd test for match
je seekstring101 ;jump if found
pop di ;match not made
pop si ;restore prior ptrs
inc si ;forward strx ptr
jmp short seekstring31 ;resume search for 1st ch
seekstring101: loop seekstring71 ;go compare next char
pop di ;substring found!
pop si ;balance stack
jmp short seekstring1 ;go set return value
seekstring111: sub bl,bl ;return 0
seekstring1: sub bh,bh ;return in bl, clear bh
mov ax,bx ;set return value
pop ds ;restore ds
mov bx,bp ;get return value
mov TPFError,bl ;set TPFError
pop bp ;restore bp and quit
ret 10
seekstring endp
;-------------------------------------------------------------------------------
;function stringof(substrg: stype; length :integer): stype;
;-------------------------------------------------------------------------------
;
data segment
extrn TPFError :byte
data ends
;
stringof proc far
push bp ;save bp
mov bp,sp ;set up stack frame
mov TPFError,1 ;1 = error
push ds ;save ds
les di,dword ptr[bp+12] ;es:di pts to return string
lds si,dword ptr[bp+8] ;ds:si pts to substring
mov byte ptr es:[di],0 ;return null string if error
mov cx,[bp+6] ;return string length
jcxz stringof3 ;quit if null
sub ch,ch ;255 max
mov dl,[si] ;get substring length
mov dh,dl ;copy in dh
or dl,dl ;test for zero length
jz stringof3 ;quit if zero
mov es:[di],cl ;set return strx descriptor
mov bx,si ;copy strx start point
stringof1: inc di ;forward ret strx ptr
inc si ;forward strx ptr
mov al,[si] ;get character
mov es:[di],al ;write character
dec cx ;finished yet?
jz stringof2 ;quit if so
dec dl ;end of strx yet?
jnz stringof1 ;loop if not
mov dl,dh ;renew strx counter
mov si,bx ;si back to start of strx
jmp short stringof1 ;go start strx again
stringof2: pop ds ;restore ds
dec TPFError ;0 = no error
jmp short stringof4 ;jump ahead
stringof3: pop ds ;terminate with error
stringof4: pop bp ;restore bp and quit
ret 6
stringof endp
;-------------------------------------------------------------------------------
;procedure uppercase(var strx: stype);
;-------------------------------------------------------------------------------
;
uppercase proc far
mov bx,sp ;bx points to stack
les di,ss:dword ptr[bx+4] ;es:di pts to string
sub cx,cx ;clear cx
mov cl,es:[di] ;get string length
jcxz uppercase3 ;quit if null
uppercase1: inc di ;pt to next char of strx
cmp es :byte ptr [di],'z' ;test high char
ja uppercase2 ;skip ahead if above
cmp es :byte ptr [di],'a' ;test low char
jb uppercase2 ;skip ahead if below
sub es :byte ptr [di],32 ;change the char
uppercase2: loop uppercase1 ;go test next character
uppercase3: ret 4
uppercase endp
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
;function wordcount(strx: stype) :integer;
;
;
wordcount proc far
mov bx,sp ;bx points to stack
les di,ss:dword ptr[bx+4] ;point es:di to string
sub dx,dx ;clear dx as counter
mov cx,dx ;clear cx
mov cl,es:[di] ;get string descriptor
mov al,32 ;al holds space char
wordcount1: jcxz wordcount3 ;jump ahead at eol
inc di ;forward pointer
dec cx ;dec strx counter
cmp es:[di],al ;char a space?
je wordcount1 ;loop if so
inc dx ;word starts -- inc ctr
wordcount2: jcxz wordcount3 ;jump ahead at eol
inc di ;forward pointer
dec cx ;dec strx counter
cmp es:[di],al ;char a space?
je wordcount1 ;back to spc loop if so
jmp short wordcount2 ;else next word char
wordcount3: mov ax,dx ;set return value
ret 4
wordcount endp
code ends
end